package com.ms.springDemo.controller;

import com.ms.springDemo.Events;
import com.ms.springDemo.States;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.messaging.Message;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.access.StateMachineAccess;
import org.springframework.statemachine.access.StateMachineFunction;
import org.springframework.statemachine.config.StateMachineBuilder;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.support.DefaultStateMachineContext;
import org.springframework.statemachine.support.StateMachineInterceptorAdapter;
import org.springframework.statemachine.transition.Transition;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author qingqing.liang
 * @create 2017-12-20
 **/
@Slf4j
@RestController
public class RestfulController {

    private int count = 0;

    private StateMachine<String,String> stateMachine ;

    /**
     * 状态机重启，跳过已经执行过的状态。
     *
     * @return
     */
    @RequestMapping("/restart")
    public String restart() throws Exception {
        StateMachine<String,String> stateMachine = getStateMachine();
        doWithAllRegions(stateMachine);

        stateMachine.stop();
        stateMachine.start();
        stateMachine.sendEvent(Events.EVENT1.name());
        stateMachine.sendEvent(Events.EVENT2.name());
        return "重启完成";
    }

    private StateMachine<String,String> getStateMachine() throws Exception {
        StateMachineBuilder.Builder<String, String> builder = StateMachineBuilder.builder();

        //作用
        builder.configureConfiguration().withConfiguration().beanFactory(new StaticListableBeanFactory());
        StateMachine<String,String> stateMachine = null;

        builder.configureTransitions()
                .withExternal().source(States.STATE1.name()).target(States.STATE2.name()).event(Events.EVENT1.name())

            .and().withExternal().source(States.STATE2.name()).target(States.STATE3.name()).event(Events.EVENT2.name())
            //.and().withExternal().source(States.STATE3.name()).target("").event("")
        ;

        builder.configureStates().withStates().initial(States.STATE1.name());
        stateMachine = builder.build();
        return stateMachine;
    }


    private void addListener(StateMachine<String,String> stateMachine){
        //stateMachine.addStateListener();
    }
    private void doWithAllRegions(StateMachine<String,String> stateMachine){

        stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<String, String>>() {
            @Override
            public void apply(StateMachineAccess<String, String> function) {

                ////状态机没有启动就会执行
                //log.info("==================运行，count:{}",count++);




                //状态机拦截器，发送事件之后没有拦截？
                function.addStateMachineInterceptor(new StateMachineInterceptorAdapter<String, String>() {
                    @Override
                    public void preStateChange(State<String, String> state, Message<String> message,
                                               Transition<String, String> transition, StateMachine<String, String> stateMachine) {
                        log.info("==================运行，count:{}",count++);
                    }
                });
            }
        });

    }

    private void unKnow(StateMachine<String,String> stateMachine){
        stateMachine
                .getStateMachineAccessor()
                .doWithAllRegions(access ->
                        access.resetStateMachine(
                                new DefaultStateMachineContext<String, String>(sourceState, null, null, null)));
    }


}
